import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ParticleExample(),
    );
  }
}

class ParticleExample extends StatefulWidget {
  @override
  _ParticleExampleState createState() => _ParticleExampleState();
}

class _ParticleExampleState extends State<ParticleExample> with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    )..addListener(() => setState(() {}));
    controller.forward();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          margin: EdgeInsets.only(top: 100),
          child: Particles(
            controller: controller,
            count: 20,
            size: Tween<double>(begin: 0.1, end: 1.0).animate(CurvedAnimation(
              parent: controller,
              curve: Curves.linear,
            )),
          ),
        ),
      ),
    );
  }
}

class Particles extends StatelessWidget {
  final int count;
  final Animation<double> size;
  final AnimationController controller;

  Particles({required this.count, required this.size, required this.controller});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
      child: Stack(
        children: List.generate(
          count,
              (index) => Positioned(
            left: Tween<double>(begin: 0, end: 1).animate(controller).value,
            top: Tween<double>(begin: 0, end: 1).animate(controller).value,
            child: Opacity(
              opacity: size.value,
              child: Container(
                width: size.value * 1,
                height: size.value * 1,
                color: Colors.blue.shade200,
              ),
            ),
          ),
        ),
      ),
    );
  }
}